31

您所在的位置:网站首页 ndarray 数据类型转换 31

31

2024-06-09 02:25| 来源: 网络整理| 查看: 265

31_Pandas.DataFrame,Series和NumPy数组ndarray相互转换

pandas.DataFrame,pandas.Series与NumPy配列numpy.ndarray相互关联変转换できる。

获取具有DataFrame系列的值属性的ndarray从NumPy数组ndarray生成DataFrame有关内存共享的注意事项(查看和复制)Pandas0.24.0或更高版本:to_numpy()

每个示例都将用示例代码进行描述。

此外,pandas.DataFrame和pandas.Series也具有称为as_matrix()的方法,该方法返回numpy.ndarray,但自0.23.0版本以来已弃用(不赞成使用)。

获取带有Pandas.DataFrame,Series属性值的NumPy数组ndarray

pandas.DataFrame和pandas.Series都可以获取带有值属性的NumPy数组numpy.ndarray。从pandas 0.24.0开始,建议使用末尾引入的to_numpy()方法。

对于pandas.DataFrame。

import numpy as np import pandas as pd df = pd.DataFrame(data=[[1, 2, 3], [4, 5, 6]], columns=['a', 'b', 'c']) print(df) # a b c # 0 1 2 3 # 1 4 5 6 a_df = df.values print(a_df) # [[1 2 3] # [4 5 6]] print(type(a_df)) # print(a_df.dtype) # int64

对于pandas.Series。

s = df['a'] print(s) # 0 1 # 1 4 # Name: a, dtype: int64 a_s = s.values print(a_s) # [1 4] print(type(a_s)) # print(a_s.dtype) # int64

可以获取的ndarray的数据类型dtype与原始pandas.DataFrame和pandas.Series的dtype相同。

df_f = pd.DataFrame([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]) print(df_f) # 0 1 2 # 0 0.1 0.2 0.3 # 1 0.4 0.5 0.6 a_df_f = df_f.values print(a_df_f) # [[0.1 0.2 0.3] # [0.4 0.5 0.6]] print(type(a_df_f)) # print(a_df_f.dtype) # float64

Pandas.DataFrame是数字和字符串的组合,是对象类型ndarray。

df_multi = pd.read_csv('./data/31/sample_pandas_normal.csv') print(df_multi) # name age state point # 0 Alice 24 NY 64 # 1 Bob 42 CA 92 # 2 Charlie 18 CA 70 # 3 Dave 68 TX 70 # 4 Ellen 24 CA 88 # 5 Frank 30 NY 57 a_df_multi = df_multi.values print(a_df_multi) # [['Alice' 24 'NY' 64] # ['Bob' 42 'CA' 92] # ['Charlie' 18 'CA' 70] # ['Dave' 68 'TX' 70] # ['Ellen' 24 'CA' 88] # ['Frank' 30 'NY' 57]] print(type(a_df_multi)) # print(a_df_multi.dtype) # object

如果仅要将DataFrame的特定列转换为ndarray,则可以获取提取该列的DataFrame的值。有关列提取,请参见以下文章。

28_Pandas通过index选择并获取行和列

如果仅选择一列数字,则ndarray的类型将是该类型,而不是object。

a_df_int = df_multi[['age', 'point']].values print(a_df_int) # [[24 64] # [42 92] # [18 70] # [68 70] # [24 88] # [30 57]] print(type(a_df_int)) # print(a_df_int.dtype) # int64

在某些情况下,使用.T可能会更容易。

print(a_df_int.T) # [[24 42 18 68 24 30] # [64 92 70 70 88 57]]

还可以指定条件以仅提取特定类型的列。例如,如果只想提取int64类型的列,则可以编写如下。

a_df_int = df_multi.select_dtypes(include=int).values print(a_df_int) # [[24 64] # [42 92] # [18 70] # [68 70] # [24 88] # [30 57]] print(type(a_df_int)) # print(a_df_int.dtype) # int64

有关使用select_dtypes()按数据类型dtype提取列的更多信息,请参见以下文章。

29_pandas.DataFrame中提取(选择)特定类型dtype的列 另外,也可以仅提取满足条件的行名/列名的行/列。请参阅下面的文章。30_Pandas.DataFrame提取(选择)指定行名和列名的行和列

原始的pandas.DataFrame和转换后的numpy.ndarray可能共享内存,而更改一个值可能会更改另一个值。见下文。

从NumPy数组ndarray生成pandas.DataFrame,Series

可以在pandas.DataFrame和pandas.Series的构造函数的第一个参数数据中指定NumPy数组numpy.ndarray。如稍后所述,numpy.ndarray和生成的pandas.DataFrame和pandas.Series共享内存。

生成pandas.Series

如果在构造函数中未指定其他任何参数,则它将是原始ndarray类型的Series。

import numpy as np import pandas as pd a = np.arange(4) print(a) # [0 1 2 3] s = pd.Series(a) print(s) # 0 0 # 1 1 # 2 2 # 3 3 # dtype: int64

还可以指定索引名称index,系列名称,数据类型dtype等作为参数。

index = ['A', 'B', 'C', 'D'] name = 'sample' s = pd.Series(data=a, index=index, name=name, dtype='float') print(s) # A 0.0 # B 1.0 # C 2.0 # D 3.0 # Name: sample, dtype: float64

在Series构造函数中为数据指定多维ndarray会导致错误。

a = np.arange(12).reshape((4, 3)) print(a) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11]] # s = pd.Series(a) # print(s) # Exception: Data must be 1-dimensional

例如,可以选择二维ndarray的行和列并将其转换为pandas.Series。

s = pd.Series(a[2]) print(s) # 0 6 # 1 7 # 2 8 # dtype: int64 s = pd.Series(a.T[2]) print(s) # 0 2 # 1 5 # 2 8 # 3 11 # dtype: int64 生成pandas.DataFrame

与Series一样,如果未在构造函数中指定其他任何参数,则它将是原始ndarray类型的DataFrame。

a = np.arange(12).reshape((4, 3)) print(a) # [[ 0 1 2] # [ 3 4 5] # [ 6 7 8] # [ 9 10 11]] df = pd.DataFrame(a) print(df) # 0 1 2 # 0 0 1 2 # 1 3 4 5 # 2 6 7 8 # 3 9 10 11

还可以使用参数指定行名称索引,列名称列,数据类型dtype等。

index = ['A', 'B', 'C', 'D'] columns = ['a', 'b', 'c'] df = pd.DataFrame(data=a, index=index, columns=columns, dtype='float') print(df) # a b c # A 0.0 1.0 2.0 # B 3.0 4.0 5.0 # C 6.0 7.0 8.0 # D 9.0 10.0 11.0 有关内存共享的注意事项(查看和复制)

通过值属性或构造函数相互转换的Pandas.DataFrame或pandas.Series和numpy.ndarray可能彼此共享内存。如果共享内存(一个是另一个视图),则更改一个值将更改另一个。如果要分别处理和使用它们,请务必小心。

下面的示例代码及其结果来自熊猫0.25.1。行为可能因版本而异。

values属性

首先,在以下情况下。

df = pd.DataFrame(data=[[1, 2, 3], [4, 5, 6]], columns=['a', 'b', 'c']) print(df) # a b c # 0 1 2 3 # 1 4 5 6 a_values = df.values print(a_values) # [[1 2 3] # [4 5 6]]

值返回一个视图,更改一个值将更改另一个值。可以通过np.shares_memory()确定。

print(np.shares_memory(a_values, df)) # True a_values[0, 0] = 100 print(a_values) # [[100 2 3] # [ 4 5 6]] print(df) # a b c # 0 100 2 3 # 1 4 5 6

它并不总是返回视图,例如,如果每列具有不同的数据类型dtaepe,则返回副本。

df_if = pd.DataFrame(data=[[1, 0.1], [2, 0.2]], columns=['int', 'float']) print(df_if) # int float # 0 1 0.1 # 1 2 0.2 print(df_if.dtypes) # int int64 # float float64 # dtype: object a_values_if = df_if.values print(a_values_if) # [[1. 0.1] # [2. 0.2]] print(np.shares_memory(a_values_if, df_if)) # False a_values_if[0, 0] = 100 print(a_values_if) # [[100. 0.1] # [ 2. 0.2]] print(df_if) # int float # 0 1 0.1 # 1 2 0.2

另外,在通过指定行和列等范围获取值时,视图或副本可能会根据指定方法而有所不同。

print(df[['a', 'c']].values) # [[100 3] # [ 4 6]] print(np.shares_memory(df[['a', 'c']].values, df)) # False print(df.iloc[:, ::2].values) # [[100 3] # [ 4 6]] print(np.shares_memory(df.iloc[:, ::2].values, df)) # True

如果视图存在问题,则可以使用值的copy()显式创建一个副本。

a_values_copy = df.values.copy() print(a_values_copy) # [[100 2 3] # [ 4 5 6]] print(np.shares_memory(a_values_copy, df)) # False a_values_copy[0, 0] = 10 print(a_values_copy) # [[10 2 3] # [ 4 5 6]] print(df) # a b c # 0 100 2 3 # 1 4 5 6 pandas.DataFrame,pandas.Series的构造方法

将numpy.ndarray传递给构造函数pandas.DataFrame()和pandas.Series()时,共享内存。更改一个值也会更改另一个值。

a = np.array([[1, 2, 3], [4, 5, 6]]) print(a) # [[1 2 3] # [4 5 6]] df_a = pd.DataFrame(a, columns=['a', 'b', 'c']) print(df_a) # a b c # 0 1 2 3 # 1 4 5 6 print(np.shares_memory(a, df_a)) # True a[0, 0] = 100 print(a) # [[100 2 3] # [ 4 5 6]] print(df_a) # a b c # 0 100 2 3 # 1 4 5 6 df_a.iat[1, 0] = 10 print(df_a) # a b c # 0 100 2 3 # 1 10 5 6 print(a) # [[100 2 3] # [ 10 5 6]]

如果不想共享内存,请使用numpy.ndarray的copy()将copy指定为构造函数的参数。

df_a_copy = pd.DataFrame(a.copy(), columns=['a', 'b', 'c']) print(df_a_copy) # a b c # 0 100 2 3 # 1 10 5 6 a[0, 0] = 1 print(a) # [[ 1 2 3] # [10 5 6]] print(df_a_copy) # a b c # 0 100 2 3 # 1 10 5 6 Pandas0.24.0或更高版本:to_numpy()

在pandas 0.24.0中,to_numpy()方法已添加到pandas.DataFrame和pandas.Series。返回numpy.ndarray,类似于上面的属性值。

官方文档建议使用to_numpy()方法代替值属性,但是从0.25.1版本开始,即使您使用值属性也没有警告。

df = pd.DataFrame(data=[[1, 2, 3], [4, 5, 6]], columns=['a', 'b', 'c']) print(df) # a b c # 0 1 2 3 # 1 4 5 6 a = df.to_numpy() print(a) # [[1 2 3] # [4 5 6]] print(type(a)) #

默认情况下,它可能会返回一个视图(共享内存的numpy.ndarray)以及值属性。

print(np.shares_memory(df, a)) # True a[0, 0] = 100 print(a) # [[100 2 3] # [ 4 5 6]] print(df) # a b c # 0 100 2 3 # 1 4 5 6

如果copy参数为True,则返回一个副本。默认值为copy = False。

a_copy = df.to_numpy(copy=True) print(a_copy) # [[100 2 3] # [ 4 5 6]] print(np.shares_memory(df, a_copy)) # False a_copy[0, 0] = 10 print(a_copy) # [[10 2 3] # [ 4 5 6]] print(df) # a b c # 0 100 2 3 # 1 4 5 6

默认值(copy = False)也可能返回副本而不是视图。 copy = True总是返回一个副本,但是copy = False并不总是返回一个视图。

如果以上值属性返回一个副本,则默认值(copy = False)也将是一个副本。

a_cols = df[['a', 'c']].to_numpy() print(a_cols) # [[100 3] # [ 4 6]] print(np.shares_memory(df, a_cols)) # False

可以使用参数dtype指定数据类型。如果数据类型已更改,它也会返回一个副本。

a_f = df.to_numpy(dtype=float) print(a_f) # [[100. 2. 3.] # [ 4. 5. 6.]] print(np.shares_memory(df, a_f)) # False


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3